<template>
	<div class="myChart" ref="myChart"></div>
</template>

<script>
import * as Api from '@/api/index';
import axios from 'axios';
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';
import Option from './Option';
import FormatData from './FormatData.js';

export default {
	data() {
		return {
			chartRef: 'myChart',
			myChart: null,
			option: Option,
			myChartResize: Function,
			loadingOpts: {
				text: '',
				color: '#c23531',
				textColor: '#fff',
				maskColor: 'rgba(2, 16, 51, 0.8)',
				zlevel: 0,
				fontSize: 12,
				showSpinner: true,
				spinnerRadius: 20,
				lineWidth: 5,
				fontWeight: 'normal',
				fontStyle: 'normal',
				fontFamily: 'sans-serif',
			},
			colorSchemes: {
				normal: '#05c091',
				warning: '#E6A23C',
				danger: '#F56C6C',
			},
			categoryIndexDir: {},
			nodes: {
				category: [],
				db: [],
				os: [],
				net: [],
			},
			links: {
				db: [],
				os: [],
				net: [],
			},
			lines: {
				db: [],
				os: [],
				net: [],
			},
			calc: {
				radian: (2 * Math.PI) / 360,
				domWH: {
					width: 1,
					height: 1,
				},
				radius: {
					center: 0,
					category: 20,
					node: 100,
					db: 100,
					os: 100,
					net: 100,
					a1: 40,
					a2: 60,
					a3: 80,
				},
			},
			mapName: 'myMap',
			geo: {
				center: [],
				zoom: 1,
			},
			mapData: {
				category: [],
				db: [],
				os: [],
				net: [],
			},
			resizeTimer: null,
			myChartTimer: null,
			dataStatus: {
				nodes: {
					category: false,
					db: false,
					os: true,
					net: true,
				},
				coordinate: false,
				links: {
					db: false,
					os: true,
					net: true,
				},
				lines: {
					db: false,
					os: true,
					net: true,
				},
			},
			resDataStr: {
				category: '',
				db: '',
				os: '',
				net: '',
			},
		};
	},
	computed: {
		...mapGetters(['getCollapse']),
		calcRatio() {
			// xy长短轴比例
			return this.calc.domWH.width / this.calc.domWH.height;
		},
	},
	created() {
		// this.getCategories(), this.getNodesData();
		
		// this.dataStatus.coordinate = true;
		
	},
	mounted() {
		this.calc.domWH.width = this.$refs[this.chartRef].clientWidth;
		this.calc.domWH.height = this.$refs[this.chartRef].clientHeight;

		this.myChart = this.$echarts.init(this.$refs[this.chartRef], 'dark');
		this.myChart.showLoading('default', this.loadingOpts);
		this.getCategories();
		this.getNodesData();
		// this.devGetData();
		// this.devEchartData()

		// 视图同步缩放、拖拽
		this.myChart.on('graphroam', (params) => {
			let _option = this.myChart.getOption();
			if (_option.series[1].effect.show == true) {
				_option.series[1].effect.show = false;
				this.myChart.setOption(_option);
			}

			this.geo.center = [
				_option.series[0].center[0],
				_option.series[0].center[1] * -1,
			];
			this.geo.zoom = _option.series[0].zoom;

			clearTimeout(this.myChartTimer);
			this.myChartTimer = setTimeout(() => {
				_option.series[1].effect.show = true;
				_option.geo[0].center = this.geo.center;
				_option.geo[0].zoom = this.geo.zoom;
				this.myChart.setOption(_option);
			}, 1000);
		});
		// 鼠标事件，隐藏及显示特效图层
		this.myChart.on('mouseover', (params) => {
			let _option = this.myChart.getOption();

			if (
				params.seriesIndex == 0 &&
				_option.series[1].effect.show == true
			) {
				_option.series[1].effect.show = false;

				this.myChart.setOption(_option);
			}
		});
		this.myChart.on('mouseout', (params) => {
			let _option = this.myChart.getOption();

			if (
				params.seriesIndex == 0 &&
				_option.series[1].effect.show == false
			) {
				clearTimeout(this.myChartTimer);
				this.myChartTimer = setTimeout(() => {
					_option.series[1].effect.show = true;
					_option.geo[0].center = this.geo.center;
					_option.geo[0].zoom = this.geo.zoom;
					this.myChart.setOption(_option);
				}, 1000);
			}
		});

		// 图例开关
		this.myChart.on('legendselectchanged', (params) => {
			// 获取点击图例的选中状态
			var isSelected = params.selected[params.name];
			// 在控制台中打印
			console.log(
				(isSelected ? '选中了' : '取消选中了') + '图例' + params.name
			);
			// 打印所有图例的状态
			console.log(params.selected);
		});

		// 监听面板宽高变化
		this.myChartResize = () => {
			this.calc.domWH.width = this.$refs[this.chartRef].clientWidth;
			this.calc.domWH.height = this.$refs[this.chartRef].clientHeight;
		};
		window.addEventListener('resize', this.myChartResize);
	},
	methods: {
		...mapMutations('dashboard/realTimeStatus', ['setAlertInfo']),
		 getCategories() {
			// 内圈
			// Api.submitAdmin({
			// 	postData: JSON.stringify({
			// 		opera: 'GetServicesName',
			// 		curPage: 1,
			// 		pageSize: 10000,
			// 		sort: {
			// 			sortColumn: '',
			// 			sortOrders: ''
			// 		},
			// 		filtersType: 'exactquery',
			// 		filters: {}
			// 	}),
			// }).then((res) => {
			// 	if (Object.hasOwnProperty.call(res, 'data') && JSON.stringify(res.data) != this.resDataStr.category) {
			// 		this.resDataStr.category = JSON.stringify(res.data);

			// 		this.option.legend[0].data = [];
			// 		this.option.series[0].categories = [];

			// 		if (res.data.length > 0) {
			// 			let _nodes = [];

			// 			res.data.forEach((element, index) => {
			// 				this.$set(this.categoryIndexDir, element.NAME, index);
			// 				this.option.legend[0].data.push(element.NAME);
			// 				this.option.series[0].categories.push({
			// 					name: element.NAME,
			// 					itemStyle: {
			// 						color: this.colorSchemes.normal
			// 					}
			// 				});

			// 				_nodes.push({
			// 					id: index,
			// 					name: element.NAME,
			// 					symbolSize: 40,
			// 					x: 0,
			// 					y: 0,
			// 					value: index,
			// 					category: index
			// 				});
			// 			});

			// 			this.nodes.category = _nodes;
			// 			this.dataStatus.nodes.category = true;
			// 		} else {
			// 			this.$message({
			// 				message: '获取到的业务分组为空',
			// 				type: 'error'
			// 			});
			// 		}
			// 	}
			// });
			let that = this;
		

		//  axios.post('http://172.20.1.155:9003/api/Echart')
		 Api.EchartDevFetchData()
		
		 .then((res) => {
			 //数据处理
			res={
				data:{
					category:res.category
				}
			}
			
				if (
					Object.hasOwnProperty.call(res, 'data') &&
					JSON.stringify(res.data.category) !=
						this.resDataStr.category
				) {
					this.resDataStr.category = JSON.stringify(
						res.data.category
					);

					this.option.legend[0].data = [];
					this.option.series[0].categories = [];

					if (res.data.category.length > 0) {
						let _nodes = [];
						//根据不同的请求地址修改这处
						let category_data = res.data.category;
						category_data.forEach((element, index) => {
							
							this.$set(
								this.categoryIndexDir,
								element.name,
								index
							);
							this.option.legend[0].data.push(element.name);
							this.option.series[0].categories.push({
								name: element.name,
								itemStyle: {
									color: that.colorSchemes.normal,
								},
							});

							_nodes.push({
								id: element.id,
								name: element.name,
								symbolSize: 40,
								x: 0,
								y: 0,
								value: index,
								itemStyle: {
									color: that.colorSchemes.normal,
								},
								category: element.category,
							});
						});

						this.nodes.category = _nodes;

						this.dataStatus.nodes.category  = true;
            // this.dataStatus.coordinate = true;

           
					} else {
						this.$message({
							message: '获取到的业务分组为空',
							type: 'error',
						});
					}
				}
			});
		},
		getNodesData() {
			// 外圈
			// Api.submitAdmin({
			// 	postData: JSON.stringify({
			// 		opera: 'GetDBMonitor',
			// 		curPage: 1,
			// 		pageSize: 10000,
			// 		sort: {
			// 			sortColumn: '',
			// 			sortOrders: '',
			// 		},
			// 		filtersType: 'fuzzyquery',
			// 		filters: {},
			// 	}),
			// }).then((res) => {
			// 	if (Object.hasOwnProperty.call(res, 'data') && JSON.stringify(res.data) != this.resDataStr.db) {
			// 		this.resDataStr.db = JSON.stringify(res.data);

			// 		let _nodes = [];
			// 		res.data.forEach((element, index) => {
			// 			let _category = this.categoryIndexDir[element.SERVICESNAME] ? this.categoryIndexDir[element.SERVICESNAME] : this.categoryIndexDir['默认业务系统'];
			// 			let _itemStyle = { color: this.colorSchemes.normal };
			// 			let _random = Math.floor(Math.random() * Math.floor(10));
			// 			if (_random > 7) {
			// 				_itemStyle.color = this.colorSchemes.danger;
			// 			} else if (_random > 4) {
			// 				_itemStyle.color = this.colorSchemes.warning;
			// 			}

			// 			_nodes.push({
			// 				id: element.CID,
			// 				name: element.DB_SERVERNAME,
			// 				symbolSize: 15,
			// 				x: 0,
			// 				y: 0,
			// 				value: index + ': ' + element.SERVICESNAME,
			// 				category: _category,
			// 				itemStyle: _itemStyle
			// 			});
			// 		});

			// 		this.nodes.db = _nodes;
			// 		this.dataStatus.nodes.db = true;
			// 	} else if (typeof(res) == 'string'){
			// 		this.$message({
			// 			message: res,
			// 			type: 'error'
			// 		});
			// 	}
			// });
			let that = this;

			// axios.post('http://172.20.1.155:9003/api/Echart')
			Api.EchartDevFetchData()
			.then((res) => {
				res={
				data:{
					db:res.db
				}
			}
				if (
					Object.hasOwnProperty.call(res, 'data') &&
					JSON.stringify(res.data.db) != this.resDataStr.db
				) {
					this.resDataStr.db = JSON.stringify(res.data.db);

					let _nodes = [];
					//根据不同的请求地址修改这处
					let _data = res.data.db;
					_data.forEach((element, index) => {
						// let _category = this.categoryIndexDir[element.SERVICESNAME] ? this.categoryIndexDir[element.SERVICESNAME] : this.categoryIndexDir['默认业务系统'];
						let _category = this.categoryIndexDir[
							element.SERVICESNAME
						]
							? this.categoryIndexDir[element.name]
							: this.categoryIndexDir['默认业务系统'];
						// console.log(this.categoryIndexDir[element.name],'7')
						// let _itemStyle = { color: this.colorSchemes.normal };
						let _itemStyle = '';

						// let _random = Math.floor(Math.random() * Math.floor(10));
						// if (_random > 7) {
						//   _itemStyle.color = this.colorSchemes.danger;
						// } else if (_random > 4) {
						//   _itemStyle.color = this.colorSchemes.warning;
						// }

						let item_style_item = 0;
						let item_style_item_color = 0;
						for (let i = 0; i < index; i++) {
							if (item_style_item > 4) {
								item_style_item = 0;
								item_style_item_color += 1;
							}
							if (item_style_item_color > 2) {
								item_style_item_color = 0;
							}

							switch (item_style_item_color) {
								case 0:
									_itemStyle = {
										color: that.colorSchemes.normal,
									};

									break;
								case 1:
									_itemStyle = {
										color: that.colorSchemes.warning,
									};

									break;
								case 2:
									_itemStyle = {
										color: that.colorSchemes.danger,
									};

									break;
							}

							item_style_item += 1;
						}

						_nodes.push({
							id: element.id,
							name: element.name,
							symbolSize: 15,
							x: 0,
							y: 0,
							// value: index + ': ' + element.SERVICESNAME,
							value: index + ': ' + element.name,
							category: _category,
							itemStyle: _itemStyle,
						});
					});

					this.nodes.db = _nodes;

					this.dataStatus.coordinate = true;
					
          this.dataStatus.nodes.category = true;
					this.dataStatus.nodes.db = true;
          
				} else if (typeof res == 'string') {
					this.$message({
						message: res,
						type: 'error',
					});
				}
			});
		},

		devGetData() {
			Api.devFetchData().then((res) => {
				this.myChart.hideLoading();

				res.nodes.forEach(function(node) {
					node.label = {
						show: node.symbolSize > 30,
					};
				});
				this.option.legend[0].data = res.categories.map((a) => {
					return a.name;
				});

				this.option.series[0].data = res.nodes;
				let _smallNodeNum = 0;
				this.option.series[0].data = res.nodes.map((item) => {
					let _n = Math.floor(Math.random() * Math.floor(10));
					if (_n > 7) {
						item.itemStyle = {
							color: this.colorSchemes.danger,
						};
					} else if (_n > 4) {
						item.itemStyle = {
							color: this.colorSchemes.warning,
						};
					} else {
						item.itemStyle = {
							color: this.colorSchemes.normal,
						};
					}

					let _radiusKey = '';
					if (item.symbolSize < 10) {
						_radiusKey = 'node';
						_smallNodeNum += 1;
					} else if (item.symbolSize < 20) {
						_radiusKey = 'a3';
					} else if (item.symbolSize < 30) {
						_radiusKey = 'a2';
					} else if (item.symbolSize < 40) {
						_radiusKey = 'a1';
					} else {
						_radiusKey = 'center';
					}
					item.r = this.calc.radius[_radiusKey];
					return item;
				});
				this.option.series[0].links = res.links;
				this.option.series[0].categories = res.categories;

				let _n =
					360 / (this.option.series[0].data.length - _smallNodeNum);
				let _m = 360 / _smallNodeNum;
				let _m2 = 0;
				// this.option.series[0].data.forEach((element, index) => {
				//   let _r = 0;
				//   if (element.r === this.calc.radius.node) {
				//     _r = this.calc.radian * (_m2 * _m);
				//     _m2 += 1;
				//   } else {
				//     _r = this.calc.radian * (index + index * _n);
				//   }

				//   element.x = 0 + Math.sin(_r) * element.r * this.calcRatio;
				//   element.y = 0 - Math.cos(_r) * element.r;
				// });

				this.myChart.setOption(this.option);

				// this.devTimer(_n, _m);
			});
		},
		devTimer(n, m) {
			let _m = 0;
			let _m2 = 0;
			setInterval(() => {
				this.option.series[0].data.forEach((element, index) => {
					let _r = 0;
					if (element.r === this.calc.radius.node) {
						_r = this.calc.radian * (_m2 * m + _m);
						_m2 += 1;
					} else if (element.r === this.calc.radius.center) {
						// _r = this.calc.radian * (index + index * n + _m);
					} else {
						_r = this.calc.radian * (index + index * n + _m * -1);
					}

					element.x = 0 + Math.sin(_r) * element.r * this.calcRatio;
					// element.x = 0 + Math.sin(_r) * element.r * this.calc.ratio;
					element.y = 0 - Math.cos(_r) * element.r;

					// element.symbolSize = 10;
				});
				_m += 10;
				_m2 = 0;
				this.myChart.setOption(this.option);
			}, 1000);
		},
		setOption() {
			this.myChart.hideLoading();

			// nodes
			let _nodes = [];
			for (const key in this.nodes) {
				const element = this.nodes[key];
				_nodes.push(...element);
			}
			this.option.series[0].data = _nodes;

			// map
			let _map = {
				type: 'FeatureCollection',
				features: [],
			};
			for (const key in this.mapData) {
				const element = this.mapData[key];
				_map.features.push(...element);
			}
			this.$echarts.registerMap(this.mapName, _map);
			this.option.geo.map = this.mapName;

			// links
			let _links = [];
			for (const key in this.links) {
				const element = this.links[key];
				_links.push(...element);
			}
			this.option.series[0].links = _links;

			// lines
			let _lines = [];
			for (const key in this.lines) {
				const element = this.lines[key];
				_lines.push(...element);
			}
			this.option.series[1].data = _lines;

			// setOption
			this.myChart.setOption(this.option);

			// 重置状态
			for (const key in this.dataStatus) {
				if (typeof this.dataStatus[key] == 'object') {
					for (const j in this.dataStatus[key]) {
						this.dataStatus[key][j] = false;
					}
				} else {
					this.dataStatus[key] = false;
				}
			}
		},
		calcCoordinate(type = 'all') {
			let _keyArr = [];
			if (type === 'all') {
				for (const key in this.nodes) {
					_keyArr.push(key);
				}
			} else {
				_keyArr.push(type);
			}

			_keyArr.forEach((key) => {
				let _n = 360 / this.nodes[key].length;
				let _mapData = [];

				this.nodes[key].forEach((element, index) => {
					let _r = this.calc.radian * index * _n;

					element.x =
						0 +
						Math.sin(_r) * this.calc.radius[key] * this.calcRatio;
					// element.x = 0 + Math.sin(_r) * this.calc.radius[key] * this.calc.ratio;
					element.y = 0 - Math.cos(_r) * this.calc.radius[key];

					_mapData.push({
						type: 'Feature',
						properties: {},
						geometry: {
							type: 'MultiPolygon',
							coordinates: [[[[element.x, element.y * -1]]]],
						},
					});
				});

				this.mapData[key] = _mapData;
				// this.dataStatus.coordinate = true;
			});
		},
		createLinks(type = 'all') {
			let that = this;
			let _keyArr = [];
			let _index = this.nodes.category.length;

			if (type === 'all') {
				for (const key in this.links) {
					_keyArr.push(key);
				}
			} else {
				_keyArr.push(type);
			}

			_keyArr.forEach((key) => {
				let _links = [];
				let _lines = [];

				this.nodes[key].forEach((element, index) => {
					let lineColor = '';
					//   index = (index + 1) % 30;
					//   console.log(index)
					// for(let i=0;i<index;i++){
					// 	switch ((index+1) % 3) {
					//     case 0:
					//       lineColor = { color: that.colorSchemes.normal };

					//       break;
					//     case 1:
					//       lineColor = { color: that.colorSchemes.warning };

					//       break;
					//     case 2:
					//       lineColor = { color: that.colorSchemes.danger };

					//       break;
					//   }

					// }
					let j = 0;
					let item_color = 0;
					for (let i = 0; i < index; i++) {
						if (j > 9) {
							j = 0;
							item_color += 1;
						}
						if (item_color > 2) {
							item_color = 0;
						}

						switch (item_color) {
							case 0:
								lineColor = { color: that.colorSchemes.normal };

								break;
							case 1:
								lineColor = {
									color: that.colorSchemes.warning,
								};

								break;
							case 2:
								lineColor = { color: that.colorSchemes.danger };

								break;
						}

						j += 1;
					}

					//   { color: element.itemStyle.color }
					_links.push({
						source: _index,
						target: element.category,
						lineStyle: lineColor,
					});

					_lines.push({
						coords: [
							[
								this.nodes.category[element.category].x,
								this.nodes.category[element.category].y * -1,
							],
							[element.x, element.y * -1],
						],
					});
					this.dataStatus.nodes.category = false;
          

					_index++;
				});

				this.links[key] = _links;
				this.dataStatus.links[key] = true;
				this.lines[key] = _lines;
				this.dataStatus.lines[key] = true;
				this.dataStatus.nodes.category = false;
        
			});
		},
		verifyData() {
			let _flagJson = {
				nodes: true,
				links: true,
				lines: true,
			};
			for (const key in this.dataStatus) {
				for (const j in this.dataStatus[key]) {
					const element = this.dataStatus[key][j];
					if (element == false) {
						_flagJson[j] = element;
						break;
					}
				}
			}

			return _flagJson;
		},
	},
	watch: {
		getCollapse: function() {
			clearTimeout(this.resizeTimer);
			this.resizeTimer = setTimeout(() => {
				this.calc.domWH.width = this.$refs[this.chartRef].clientWidth;
				this.calc.domWH.height = this.$refs[this.chartRef].clientHeight;
			}, 300);
		},
		calcRatio: function() {
			this.myChart.resize();
			if (this.nodes.category.length > 0) {
				this.calcCoordinate();
			}
		},
		'dataStatus.nodes': {
			handler: function(nodes) {
				if (nodes.category && nodes.db) {
					this.calcCoordinate();
				}
			},
			deep: true,
		},
		'dataStatus.coordinate': {
			handler: function(val) {
				
				if (val) {
					this.createLinks('all');
				}
			},
		},
		'dataStatus.links': {
			handler: function(links) {
				if (links.db) {
					this.setOption();
				}
			},
			deep: true,
		},
	},
	beforeDestroy() {
		window.removeEventListener('resize', this.myChartResize);
		this.myChart.off();
		this.myChart.dispose();
	},
};
</script>

<style scoped>
.myChart {
	height: 100%;
}
</style>
